package com.kitty.game.mirror.service;

import com.kitty.common.db.Db4CommonService;
import com.kitty.common.utils.SpringUtils;
import com.kitty.game.config.NPC;
import com.kitty.game.fight.bean.Fight;
import com.kitty.game.fight.factory.FightFactory;
import com.kitty.game.fight.service.CountService;
import com.kitty.game.fight.service.FightService;
import com.kitty.game.mirror.MirrorDataPool;
import com.kitty.game.pet.model.Pet;
import com.kitty.game.role.message.RespAppear;
import com.kitty.game.role.message.RespUpdateAppearance;
import com.kitty.game.role.model.Role;
import com.kitty.mina.cache.DataCache;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import com.kitty.game.mirror.model.FightMirror;
import com.kitty.game.mirror.model.MirrorFightParam;
import com.kitty.game.mirror.model.PetMirror;
import com.kitty.game.mirror.model.RoleMirror;

@Service
public class FightMirrorService {
    private Logger logger = LoggerFactory.getLogger(getClass());
    /**
     * 血量系数，镜像血量是玩家的3倍
     */
    private static final int LIFE_RATE = 3;

    /**
     * 根据玩家数据生成镜像
     */
    public FightMirror createFightMirror(long id, Role role) {
        return createFightMirror(id, role, LIFE_RATE);
    }

    /**
     * 根据玩家数据生成镜像
     */
    public FightMirror createFightMirror(long id, Role role, int lifeRate) {
        FightMirror fightMirror = new FightMirror();
        fightMirror.setId(id);
        fightMirror.setRoleMirror(createRoleMirror(role, lifeRate));
        fightMirror.setPetMirror(createPetMirror(role, lifeRate));
        return fightMirror;
    }

    private RoleMirror createRoleMirror(Role role, int lifeRate) {
        RoleMirror roleMirror = new RoleMirror();
        roleMirror.setUid(role.getUid());
        roleMirror.setName(role.getName());
        roleMirror.setLevel(role.getLevel());
        roleMirror.setTao(role.getTao());
        roleMirror.setDefense(role.getMaxDefense());
        roleMirror.setSpeed(role.getMaxSpeed());
        roleMirror.setMagPower(role.getMagPower() * lifeRate);
        roleMirror.setPhyPower(role.getMaxPhyPower() * lifeRate);
        roleMirror.setMaxLife(role.getMaxLife() * lifeRate);
        roleMirror.setMaxMana(role.getMaxMana());

        List<Integer> skillIds = MirrorDataPool.getSkillIds((byte) role.getPolar(), role.getLevel());
        roleMirror.setSkillIds(new ArrayList<>(skillIds));

        roleMirror.setIcon(role.getRoleIcon());
        roleMirror.setPolar(role.getPolar());
        roleMirror.setSuitIcon(role.getSuitId());
        roleMirror.setMountIcon(0);
        roleMirror.setMountPosture(0);
        roleMirror.setFasionIcon(role.getFasionIcon());

        roleMirror.setWeaponIcon((short) role.getWeaponIcon());
        roleMirror.setSuitLightEffect((short) role.getSuitLightId());
        roleMirror.setPartyName(role.getPartyName());

        return roleMirror;
    }

    private PetMirror createPetMirror(Role role, int lifeRate) {
        Pet pet = SpringUtils.getPetService().getPetById(role.getPetBox().getFightPetId(), role);

        PetMirror petMirror = new PetMirror();
        petMirror.setName(pet.getName());
        petMirror.setLevel(pet.getLevel());
        petMirror.setType(pet.getType());
        petMirror.setIntimacy(pet.getIntimacy());
        petMirror.setMartial(pet.getMartial());
        CountService countService = SpringUtils.getHurtService();
        petMirror.setDefense(countService.countPetMaxDefense(pet));
        petMirror.setSpeed((short) countService.countPetMaxSpeed(pet));
        petMirror.setMagPower(countService.countPetMaxMagPower(pet)* lifeRate/2);
        petMirror.setPhyPower(countService.countPetMaxPhyPower(pet)* lifeRate/2);
        petMirror.setMaxLife(countService.countPetMaxLife(pet) * lifeRate);
        petMirror.setMaxMana(countService.countPetMaxMana(pet));

        List<Integer> skillIds = SpringUtils.getSkillService().getSkillIds(pet.getSkillBox());
        petMirror.setSkillIds((ArrayList<Integer>) skillIds);

        petMirror.setIcon(pet.getIcon());
        petMirror.setPolar(pet.getPolar());

        return petMirror;
    }

    public FightMirror getFightMirror(long id) {
        return DataCache.FIGHT_MIRRORS.get(id);
    }

    /**
     * 添加战斗镜像
     */
    public void addFightMirror(FightMirror fightMirror) {
        // TODO 暂时加先锁处理，后续看怎么优化
        synchronized (DataCache.FIGHT_MIRRORS) {
            DataCache.FIGHT_MIRRORS.put(fightMirror.getId(), fightMirror);
            Db4CommonService.getInstance().add2Queue(fightMirror);
        }
    }

    /**
     * 更新战斗镜像
     */
    public void updateFightMirror(FightMirror fightMirror) {
        // TODO 暂时加先锁处理，后续看怎么优化
        synchronized (DataCache.FIGHT_MIRRORS) {
            FightMirror oldFightMirror = DataCache.FIGHT_MIRRORS.get(fightMirror.getId());
            if (oldFightMirror.getRoleMirror().getUid() == fightMirror.getRoleMirror().getUid()) {
                DataCache.FIGHT_MIRRORS.put(fightMirror.getId(), fightMirror);
                Db4CommonService.getInstance().add2Queue(fightMirror);
            }
        }
    }

    /**
     * 加载战斗镜像
     */
    public void loadFightMirrors() {
        Dao dao = SpringUtils.getBean(Dao.class);
        List<FightMirror> list = dao.query(FightMirror.class, Cnd.NEW());
        for (FightMirror fightMirror : list) {
            DataCache.FIGHT_MIRRORS.put(fightMirror.getId(), fightMirror);
        }
    }

    public void changeRespAppear(NPC npc, RespAppear respAppear) {
        FightMirror fightMirror = getFightMirror(npc.getId());
        if (fightMirror != null) {
            RoleMirror roleMirror = fightMirror.getRoleMirror();
            if (roleMirror.getTitle() != null) {
                respAppear.setTitle(roleMirror.getTitle());
            }
            respAppear.setRoleName(roleMirror.getName());
            respAppear.setIcon(roleMirror.getIcon());
            respAppear.setPortrait(roleMirror.getIcon());
            respAppear.setOrg_icon(roleMirror.getIcon());
            respAppear.setPet_icon(roleMirror.getMountIcon());
            respAppear.setMount_icon(roleMirror.getMountPosture());
            respAppear.setStatus(roleMirror.getIcon());
//            respAppear.setSpecial_icon(roleMirror.getFasionIcon());
            respAppear.setSuit_icon(roleMirror.getSuitIcon());
            respAppear.setSuit_light_effect(roleMirror.getSuitLightEffect());
            respAppear.setWeaponId(roleMirror.getWeaponIcon());
        }
    }

    public void changeRespUpdateAppearance(NPC npc, RespUpdateAppearance respUpdateAppearance) {
        FightMirror fightMirror = getFightMirror(npc.getId());
        if (fightMirror != null) {
            RoleMirror roleMirror = fightMirror.getRoleMirror();
            if (roleMirror.getTitle() != null) {
                respUpdateAppearance.setTitle(roleMirror.getTitle());
            }
            respUpdateAppearance.setRoleName(roleMirror.getName());
            respUpdateAppearance.setIcon(roleMirror.getIcon());
            respUpdateAppearance.setPortrait(roleMirror.getIcon());
            respUpdateAppearance.setOrg_icon(roleMirror.getIcon());
            respUpdateAppearance.setPet_icon(roleMirror.getMountIcon());
            respUpdateAppearance.setMount_icon(roleMirror.getMountPosture());
            respUpdateAppearance.setStatus(roleMirror.getIcon());
//            respUpdateAppearance.setSpecial_icon(roleMirror.getFasionIcon());
            respUpdateAppearance.setSuit_icon(roleMirror.getSuitIcon());
            respUpdateAppearance.setSuit_light_effect(roleMirror.getSuitLightEffect());
            respUpdateAppearance.setWeaponId(roleMirror.getWeaponIcon());
        }
    }

    public Fight startFight(Role role, MirrorFightParam mirrorFightParam) {
        FightService fightService = SpringUtils.getBean(FightService.class);
        if (fightService.isInFight(role)) {
            return null;
        }
        if (SpringUtils.getTeamService().isInTeamAndNotLeader(role)) {
            logger.warn("{}({})不是队长触发战斗", role.getUid(), role.getName());
            return null;
        }

        byte fightType = mirrorFightParam.getFightType();
        int npcId = mirrorFightParam.getNpcId();
        FightMirror fightMirror = mirrorFightParam.getFightMirror();

        Fight fight = FightFactory.getFightFactory(fightType).create(0, role, fightType, npcId, (fightMirror != null ? fightMirror : mirrorFightParam.getFightMirrorList()));
        fight.start();

        return fight;
    }
}
